﻿#include "FITKAbaqusAdaptorCase.h"
#include "FITKAbaqusINPWriter.h"
#include "FITKAbaqusINPReader.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusAdaptorPart.h"
#include "FITKAbaqusAdaptorMaterial.h"
#include "FITKAbaqusAdaptorAssembly.h"
#include "FITKAbaqusAdaptorStep.h"
#include "FITKAbaqusAdaptorAmplitude.h"
#include "FITKAbaqusAdaptorBoundary.h"
#include "FITKAbaqusAdaptorInteraction.h"
#include "FITKAbaqusAdaptorTimePoints.h"
#include "FITKAbaqusAdaptorConnectorSection.h"
#include "FITKAbaqusAdaptorPredefinedField.h"
#include "InpReadInformationMapper.h"
#include "FITKAbaqusAdaptorInteractionProperty.h"
#include "FITK_Kernel/FITKAdaptor/FITKIOAdaptorFactory.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterial.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractStep.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepInit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepFrequency.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepGeneralStatic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepDynamicExplicit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractAmplitude.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAmplitudePeriodic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAmplitudeTabular.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAmplitudeManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractBoundaryCondition.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionDisplacement.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionSymmetry.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionPropertyContact.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionPropertyManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionSurfToSurfExplicit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionGeneralContactExplicit.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInteractionManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaTimePoints.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaTimePointsManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorSection.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorAssignment.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorAssignmentManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaPredefinedFieldTemperature.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaPredefinedFieldVelocity.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaPredefinedFieldManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionVelocity.h"
namespace IO
{
    QString FITKAbaqusAdaptorCase::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorCase";
    }

    bool FITKAbaqusAdaptorCase::adaptR()
    {
        _caseData = AbaqusData::FITKDataCase::SafeDownCastFITKDataCase(_dataObj);
        if (_reader == nullptr || _caseData == nullptr) return false;

        int readLevel = _reader->getINPReadLevel();
        QString currentLine;
        while (!_reader->atEnd())
        {
            bool readOK = false;
            currentLine = _reader->readLine();
            if (!currentLine.startsWith("*")) continue;
            InpKeyLineSpliter keySpliter(currentLine, _reader);
            const QString sheader = keySpliter.getHeader().toLower();

            //发送计算进度信号
            _reader->sendCurrentPercent();

            //解析头  
            if (sheader == "heading")
            {

            }
            else if (sheader == "preprint")
            {
                readOK = this->readPreprint();
            }
            //解析Part
            else if (sheader == "part")
            {
                readOK = this->readPart();
            }
            //检测解析等级
            else if (readLevel < (int)INPReadLevel::ReadAssembly) continue;

            //解析Assembly
            else if (sheader == "assembly")
            {
                readOK = this->readAssembly();
            }
            //检测解析等级
            else if (readLevel < (int)INPReadLevel::ReadALL) continue;
            //解析Material
            else if (sheader == "material")
            {
                readOK = this->readMaterial();
            }
            //解析幅值曲线
            else if (sheader == "amplitude")
            {
                readOK = this->readAmplitude();
            }
            //解析相互作用属性
            else if (sheader == "surface interaction")
            {
                readOK = this->readInteractionProperty();
            }
            //解析时间点
            else if (sheader == "time points")
            {
                readOK = this->readTimePoints();
            }
            //解析边界
            else if (sheader == "boundary")
            {
                readOK = this->readInitialBoundary();
            }
            else if (sheader == "contact" || sheader == "contact inclusions" || sheader == "contact pair")
            {
                readOK = this->readInteraction();
            }
            else if (sheader == "connector behavior")
            {
                readOK = this->readConnectorBehavior();
            }
            else if (sheader == "initial conditions")
            {
                readOK = this->readInitialConditions();
            }
            //解析分析步
            else if (sheader == "step")
            {
                readOK = this->readStep();
            }
            else
            {
                //其余关键字

                continue;
            }

            if (readOK)
            {
                //调用解析函数后要执行 backLine函数。
                _reader->backLine();
            }
            else
            {
                //解析出错目前不做处理
                //return false;
            }
        }

        return true;
    }
    bool FITKAbaqusAdaptorCase::adaptW()
    {
        _caseData = AbaqusData::FITKDataCase::SafeDownCastFITKDataCase(_dataObj);
        if (_writer == nullptr || _caseData == nullptr) return false;
        // 写出函数主体
        QTextStream* stream = _writer->getStream();
        if (stream == nullptr) return false;
        bool isW = true;
        //写出头
        writeHeading();
        writePreprint();

        //写出Part
        int partNum = _caseData->getPartManager()->getDataCount();
        if (partNum > 0)
        {
            *stream << "**" << endl;
            *stream << "** PARTS" << endl;
            *stream << "**" << endl;

            for (int i = 0; i < partNum; ++i)
            {
                auto part = _caseData->getPartManager()->getDataByIndex(i);
                isW &= writePart(part);
                sendCalculateProgress(1, partNum, i);
            }
        }
        sendCalculateProgress(1, partNum, partNum);

        //写出ASSEMBLY等
        auto assemblyNum = _caseData->getAssembly()->getDataCount();
        if (assemblyNum > 0)
        {
            *stream << "**" << endl;
            *stream << "** ASSEMBLY" << endl;
            *stream << "**" << endl;
            auto absAssembly = _caseData->getAssembly();
            isW &= writeAssembly(absAssembly);
        }
        sendCalculateProgress(2, assemblyNum, assemblyNum);

        //写出连接器行为
        isW &= writeConnectorBehavior();
        //写出Amplitude
        int amplitudeNum = _caseData->getAmplitudeManager()->getDataCount();
        if (amplitudeNum > 0)
        {
            for (int i = 0; i < amplitudeNum; ++i)
            {
                auto absAmplitude = _caseData->getAmplitudeManager()->getDataByIndex(i);
                auto amplitude = dynamic_cast<Interface::FITKAbaAbstractAmplitude*>(absAmplitude);
                if (!amplitude) continue;
                isW &= writeAmplitude(amplitude);
            }
        }

        //写出Material
        int materialNum = _caseData->getMaterialManager()->getDataCount();
        if (materialNum > 0)
        {
            *stream << "**" << endl;
            *stream << "** MATERIALS" << endl;
            *stream << "**" << endl;
            for (int i = 0; i < materialNum; ++i)
            {
                auto absMaterial = _caseData->getMaterialManager()->getDataByIndex(i);
                auto material = dynamic_cast<Interface::FITKAbaMaterial*>(absMaterial);
                if (!material) continue;
                isW &= writeMaterial(material);
                sendCalculateProgress(3, materialNum, i);
            }
        }
        sendCalculateProgress(3, materialNum, materialNum);

        isW &= writeInteractionProperty();
        isW &= writeTimePoints();
        isW &= writeInitialBoundary();
        isW &= writeInitialConditions();
        isW &= writeInteraction();
        
        //写出Step
        int stepNum = _caseData->getStepManager()->getDataCount();
        if (stepNum > 1)
        {
            for (int i = 1; i < stepNum; ++i)
            {
                auto absStep = _caseData->getStepManager()->getDataByIndex(i);

                *stream << "** ----------------------------------------------------------------" << endl;
                *stream << "**" << endl;
                *stream << QString("** STEP: %1").arg(absStep->getDataObjectName()) << endl;
                *stream << "**" << endl;
                auto step = dynamic_cast<Interface::FITKAbaAbstractStep*>(absStep);
                if (!step) continue;
                isW &= writeStep(step);
                *stream << "*End Step" << endl;
                sendCalculateProgress(4, stepNum, i);
            }
        }
        sendCalculateProgress(4, stepNum, stepNum);

        return isW;
    }

    bool FITKAbaqusAdaptorCase::readHeading()
    {
        return true;
    }

    bool FITKAbaqusAdaptorCase::readPreprint()
    {
        QString line = _reader->previousLine();
        if (!line.startsWith("*Preprint")) return false;
        InpKeyLineSpliter s(line, _reader);
        _echo = s["echo"].size() == 3;
        _model = s["model"].size() == 3;
        _history = s["history"].size() == 3;
        _contact = s["contact"].size() == 3;
        //单行需要考虑回退机制，所以要继续读取下一行
        _reader->readLine();
        return true;
    }

    bool FITKAbaqusAdaptorCase::readPart()
    {
        AbaqusData::FITKAbaqusPart* apart = new AbaqusData::FITKAbaqusPart;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorPart>("INP", apart);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, "Create AdaptorPart Error.");
            delete apart;
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(apart);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptR();

        if (adaptor != nullptr)
            delete adaptor;

        if (!ok)
        {
            _reader->consoleMessage(3, "Read Part Error.");
            delete apart;
            return false;
        }

        _reader->consoleMessage(1, "Read Part : " + apart->getDataObjectName());
        _caseData->getPartManager()->appendDataObj(apart);
        return true;
    }

    bool FITKAbaqusAdaptorCase::readAssembly()
    {
        Interface::FITKAbaAssembly* assembly = _caseData->getAssembly();
        if (assembly == nullptr) return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorAssembly>("INP", assembly);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, "Create AdaptorAssembly Error.");
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(assembly);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptR();

        if (adaptor != nullptr)
            delete adaptor;

        if (ok)
            _reader->consoleMessage(1, "Read Assembly : " + assembly->getDataObjectName());
        else
            _reader->consoleMessage(3, "Read Assembly Error : " + assembly->getDataObjectName());
        return ok;
    }

    bool FITKAbaqusAdaptorCase::readMaterial()
    {
        Interface::FITKAbaMaterial* material = new Interface::FITKAbaMaterial;
        if (material == nullptr) return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterial>("INP", material);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, "Create AdaptorMaterial Error.");
            delete material;
            return false;
        }
        //添加到管理器中
        _caseData->getMaterialManager()->appendDataObj(material);
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(material);
        bool ok = adaptor->adaptR();

        if (adaptor != nullptr)
            delete adaptor;

        if (!ok)
        {
            _reader->consoleMessage(3, "Read Material Error : " + material->getDataObjectName());
            delete material;
            return false;
        }
        _reader->consoleMessage(1, "Read Material : " + material->getDataObjectName());
        return true;
    }

    bool FITKAbaqusAdaptorCase::readAmplitude()
    {
        //回退一行 处理关键字信息 确定单元类型
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString definition = s["definition"].toLower();
        //创建存储数据对象
        Interface::FITKAbaAbstractAmplitude* amplitude = nullptr;
        if (definition.isEmpty())
        {
            amplitude = new Interface::FITKAbaAmplitudeTabular;
        }
        else if (definition == "periodic")
        {
            amplitude = new Interface::FITKAbaAmplitudePeriodic;
        }
        if (!amplitude)return false;
        //幅值读取器
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorAmplitude>("INP", amplitude);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, "Create AdaptorAmplitude Error.");
            delete amplitude;
            return false;
        }
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(amplitude);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (!ok)
        {
            //读取成功将数据对象放入管理
            _reader->consoleMessage(3, "Read Amplitude Error : " + amplitude->getDataObjectName());
            delete amplitude;
            return false;
        }

        _reader->consoleMessage(1, "Read Amplitude : " + amplitude->getDataObjectName());
        auto ampManager = _caseData->getAmplitudeManager();
        ampManager->appendDataObj(amplitude);
        return true;
    }

    bool FITKAbaqusAdaptorCase::readInteractionProperty()
    {
        //回退一行 验证读取正确性
        _reader->backLine();
        QString lineKey = _reader->readLine();
        InpKeyLineSpliter s(lineKey, _reader);
        QString sH = s.getHeader().toLower();
        Interface::FITKAbaAbstractInteractionProperty* interactionProp = nullptr;
        if (sH == "surface interaction")
        {
            interactionProp = new Interface::FITKAbaInteractionPropertyContact;
        }
        if (!interactionProp)return false;
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorInteractionProperty>("INP", interactionProp);
        if (adaptor == nullptr)
        {
            //读取成功将数据对象放入管理
            _reader->consoleMessage(3, QString("Read Create AdaptorInteractionProperty Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            delete interactionProp;
            return false;
        }
        adaptor->setCaseData(_caseData);
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(interactionProp);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (!ok)
        {
            _reader->consoleMessage(3, QString("Read Interaction Property Error : %1, File:%2, Line:%3").arg(interactionProp->getDataObjectName()).arg(__FILE__).arg(__LINE__));
            delete interactionProp;
            return false;
        }
        //读取成功将数据对象放入管理
        _reader->consoleMessage(1, "Read Interaction Property : " + interactionProp->getDataObjectName());
        auto interactionPropertyManager = _caseData->getInteractionPropertyManager();
        interactionPropertyManager->appendDataObj(interactionProp);
        return true;
    }

    bool FITKAbaqusAdaptorCase::readInitialBoundary()
    {
        if (!_caseData || !_reader) return false;
        //回退一行 验证读取正确性
        _reader->backLine();
        QString lineKey = _reader->readLine();
        InpKeyLineSpliter s(lineKey, _reader);
        QString type = s["type"].toLower();
        //获取initStepId
        auto stepManager = _caseData->getStepManager();
        if (!stepManager)return false;
        if (stepManager->getDataCount() < 1)return false;
        int initStepId = stepManager->getDataByIndex(0)->getDataObjectID();
        do {
            QString line = _reader->readLine();
            if (line.startsWith("*"))
                break;
            QStringList str = line.split(',');
            if (str.size() < 2)return false;
            int value = str.at(1).toInt();
            int loadNum = _caseData->getBCManager()->getDataCount();
            Interface::FITKAbaAbstractBoundaryCondition* boundary = nullptr;
            if ((type.isEmpty() || type == "displacement") && str.size() == 2)
            {
                boundary = new Interface::FITKAbaBoundaryConditionSymmetry;
            }
            else if ((type.isEmpty() || type == "displacement") && value > 0 && value <= 6)
            {
                boundary = new Interface::FITKAbaBoundaryConditionDisplacement;
            }
            else if (type == "velocity" && value > 0 && value <= 6)
            {
                boundary = new Interface::FITKAbaBoundaryConditionVelocity;
            }
            if (boundary == nullptr)return false;
            boundary->setDataObjectName(QString("Boundary_%1").arg(loadNum + 1));
            boundary->setCreatedStep(initStepId);
            //通过工厂创建
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorBoundary>("INP", boundary);
            if (adaptor == nullptr)
            {
                _reader->consoleMessage(3, QString("Create AdaptorBoundary Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
                delete boundary;
                return false;
            }
            adaptor->setFileReader(_reader);
            adaptor->setDataObject(boundary);
            adaptor->setCaseData(_caseData);
            adaptor->setLineKeywords(lineKey);
            bool ok = adaptor->adaptR();
            //读取完毕释放读取器
            delete adaptor;
            if (!ok)
            {
                _reader->consoleMessage(3, QString("Read Boundary Error : %1, File:%2, Line:%3").arg(boundary->getDataObjectName()).arg(__FILE__).arg(__LINE__));
                delete boundary;
                return false;
            }
            _reader->consoleMessage(1, "Read Boundary : " + boundary->getDataObjectName());
            auto manager = _caseData->getBCManager();
            manager->appendDataObj(boundary);
        } while (!_reader->atEnd());

        return true;
    }

    bool FITKAbaqusAdaptorCase::readInteraction()
    {
        if (!_reader || !_caseData) return false;
        //回退一行 验证读取正确性
        _reader->backLine();
        QString line = _reader->readLine();
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();
        //关键字处理
        Interface::FITKAbaAbstractInteraction* dataObject{};
        if (sH == "contact pair")
        {
            dataObject = new Interface::FITKAbaInteractionSurfToSurfExplicit();
        }
        else if (sH == "contact" || sH == "contact inclusions")
        {
            dataObject = new Interface::FITKAbaInteractionGeneralContactExplicit();
            dataObject->setDataObjectName("general_contact");
        }

        if (dataObject == nullptr)
        {
            _writer->consoleMessage(3, QString("Create Interaction Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            return false;
        }
        //设置stepID -1 为默认
        dataObject->setCreatedStep(-1);
        //添加到管理器
        Interface::FITKAbaInteractionManager* _interactionManager = _caseData->getInteractionManager();
        if (_interactionManager == nullptr)return false;
        _interactionManager->appendDataObj(dataObject);

        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorInteraction>("INP", dataObject);
        if (adaptor == nullptr)
        {
            delete dataObject;
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setCaseData(_caseData);
        auto initStepData = _caseData->getStepManager()->getDataByName("Initial");
        adaptor->setStepData(initStepData);
        adaptor->setDataObject(dataObject);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok) delete dataObject;
        return ok;
    }

    bool FITKAbaqusAdaptorCase::readConnectorBehavior()
    {
        if (!_reader || !_caseData) return false;
        InpReadInformationMapper* mapper = _reader->getReadInpInformationMapper();
        //回退一行 验证读取正确性
        _reader->backLine();
        QString line = _reader->readLine();
        InpKeyLineSpliter s(line, _reader);
        //获取行为名称
        QString name = s["name"];
        Interface::FITKAbaConnectorSection* sectionConnectData = mapper->getConnectorSectionByBehaviorName(name);
        if (!sectionConnectData)return false;
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorConnectorSection>("INP", sectionConnectData);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, QString("Create ConnectorBehavior AdaptorInertia Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            return false;
        }
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(sectionConnectData);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (ok)
        {
            _reader->consoleMessage(1, "Read ConnectorBehavior success : " + name);
            return true;
        }
        _reader->consoleMessage(3, QString("Read ConnectorBehavior Error : %1, File:%2, Line:%3").arg(name).arg(__FILE__).arg(__LINE__));
        return false;
    }

    bool FITKAbaqusAdaptorCase::readStep()
    {
        QString line;
        //处理可能的描述信息
        while (!_reader->atEnd())
        {
            bool readOK = false;
            //为了结构统一 不回退直接读取下一行
            line = _reader->readLine();
            if (line.startsWith("*")) break;

        }
        //关键字处理 文件中两行可以确定类型
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();

        Interface::FITKAbaAbstractStep* stepData{};

        if (sH == "static")
        {
            stepData = new Interface::FITKAbaStepGeneralStatic();
        }
        else if (sH == "dynamic")//动力
        {
            stepData = new Interface::FITKAbaStepDynamicExplicit();
        }
        else if (sH == "frequency")
        {
            stepData = new Interface::FITKAbaStepFrequency();
        }

        if (stepData == nullptr)
        {
            _reader->consoleMessage(3, "Create Step Error, Key :" + sH);
            return false;
        }
        _caseData->getStepManager()->appendDataObj(stepData);

        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorStep>("INP", "Interface::FITKAbaAbstractStep");
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, "Create AdaptorStep Error.");
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(stepData);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptR();

        if (adaptor != nullptr)
            delete adaptor;

        if (!ok)
        {
            _reader->consoleMessage(3, "Read Step Error : " + stepData->getDataObjectName());
            delete stepData;
            return false;
        }
        _reader->consoleMessage(1, "Read Step : " + stepData->getDataObjectName());
        return true;
    }

    bool FITKAbaqusAdaptorCase::readTimePoints()
    {
        Interface::FITKAbaTimePoints* timePointData = new Interface::FITKAbaTimePoints;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorTimePoints>("INP", timePointData);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, "Create AbaTimePoints Error.");
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(timePointData);
        bool ok = adaptor->adaptR();

        if (adaptor != nullptr)
            delete adaptor;

        if (!ok)
        {
            _reader->consoleMessage(3, "Read TimePoints Error : " + timePointData->getDataObjectName());
            delete timePointData;
            return false;
        }
        _reader->consoleMessage(1, "Read TimePoints : " + timePointData->getDataObjectName());
        auto timePointManager = _caseData->getTimePointsManager();
        if (!timePointManager)return false;
        timePointManager->appendDataObj(timePointData);
        return true;
    }

    bool FITKAbaqusAdaptorCase::readInitialConditions()
    {
        if (!_reader || !_caseData) return false;
        //回退一行 验证读取正确性
        _reader->backLine();
        QString lineKeyWord = _reader->readLine();
        InpKeyLineSpliter s(lineKeyWord, _reader);
        //获取类型
        QString type = s["type"].trimmed().toUpper();
        //获取预定义管理器
        Interface::FITKAbaPredefinedFieldManager* predefinedFieldManager = _caseData->getPredefinedFieldManager();
        if (!predefinedFieldManager)return false;
        //获取initStepId
        auto stepManager = _caseData->getStepManager();
        if (!stepManager)return false;
        if (stepManager->getDataCount() < 1)return false;
        int initStepId = stepManager->getDataByIndex(0)->getDataObjectID();
        do {
            QString line = _reader->readLine();
            if (line.startsWith("*"))
                break;
            QString name;
            //创建预定义场
            Interface::FITKAbaAbstractPredefinedField* fieldData = nullptr;
            if (type == "TEMPERATURE")
            {
                fieldData = new Interface::FITKAbaPredefinedFieldTemperature;
                name = "Field";
            }
            else if (type == "VELOCITY" || type == "ROTATING VELOCITY")
            {
                fieldData = new Interface::FITKAbaPredefinedFieldVelocity;
                name = "IC";
            }
            if (!fieldData)return false;
            //设置名称和设置创建stepId
            fieldData->setDataObjectName(QString("%1-%2").arg(name).arg(predefinedFieldManager->getDataCount() + 1));
            fieldData->setCreatedStep(initStepId);
            //通过工厂创建
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorPredefinedField>("INP", fieldData);
            if (adaptor == nullptr)
            {
                _reader->consoleMessage(3, QString("Create PredefinedField Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
                delete fieldData;
                return false;
            }
            adaptor->setFileReader(_reader);
            adaptor->setDataObject(fieldData);
            adaptor->setCaseData(_caseData);
            adaptor->setLineKeywords(lineKeyWord);
            bool ok = adaptor->adaptR();
            bool isValueEmp = adaptor->isValueEmpty();
            //读取完毕释放读取器
            delete adaptor;
            //数据是否为空
            if (isValueEmp)
            {
                delete fieldData;
                continue;
            }
            if (!ok)
            {
                _reader->consoleMessage(3, QString("Read PredefinedField Error : %1, File:%2, Line:%3").arg(fieldData->getDataObjectName()).arg(__FILE__).arg(__LINE__));
                delete fieldData;
                return false;
            }
            _reader->consoleMessage(1, "Read PredefinedField : " + fieldData->getDataObjectName());
            predefinedFieldManager->appendDataObj(fieldData);
        } while (!_reader->atEnd());
        return true;
    }

    bool FITKAbaqusAdaptorCase::writeHeading()
    {
        // 写出节点函数主体
        QTextStream* stream = _writer->getStream();

        //写出固定头信息 Model Generated 暂时没读 暂时默认
        *stream << "*Heading" << endl;
        *stream << "** Model name: " << _caseData->getDataObjectName() << endl;
        *stream << "** Generated by: Abaqus/CAE 2020" << endl;
        return true;
    }

    bool FITKAbaqusAdaptorCase::writePreprint()
    {
        QString echoStr = _echo ? "YES" : "NO";
        QString modelStr = _model ? "YES" : "NO";
        QString historyStr = _history ? "YES" : "NO";
        QString contactStr = _contact ? "YES" : "NO";
        // 写出节点函数主体
        QTextStream* stream = _writer->getStream();
        *stream << QString("*Preprint, echo=%1, model=%2, history=%3, contact=%4").arg(echoStr).arg(modelStr).arg(historyStr).arg(contactStr) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorCase::writePart(AbaqusData::FITKAbaqusPart* part)
    {
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorPart>("INP", part);
        if (adaptor == nullptr) return false;
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(part);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }
    bool FITKAbaqusAdaptorCase::writeAssembly(Interface::FITKAbaAssembly* assembly)
    {
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorAssembly>("INP", assembly);
        if (adaptor == nullptr) return false;
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(assembly);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Assembly Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusAdaptorCase::writeMaterial(Interface::FITKAbaMaterial* material)
    {
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterial>("INP", material);
        if (adaptor == nullptr) return false;
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(material);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Material Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusAdaptorCase::writeAmplitude(Interface::FITKAbaAbstractAmplitude* amplitude)
    {
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorAmplitude>("INP", amplitude);
        if (adaptor == nullptr) return false;
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(amplitude);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Amplitude Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusAdaptorCase::writeInitialBoundary()
    {
        if (!_writer || !_caseData)return false;
        auto boundaryManager = _caseData->getBCManager();
        int count = boundaryManager->getDataCount();
        QTextStream* stream = _writer->getStream();
        //获取initStepId
        auto stepManager = _caseData->getStepManager();
        if (!stepManager)return false;
        if (stepManager->getDataCount() < 1)return false;
        int initStepId = stepManager->getDataByIndex(0)->getDataObjectID();
        bool okTitle = false;
        for (int i = 0; i < count; ++i)
        {
            auto boundary = dynamic_cast<Interface::FITKAbaAbstractBoundaryCondition*>(boundaryManager->getDataByIndex(i));
            if (!boundary)continue;
            if (boundary->getCreatedStep() != initStepId)continue;
            if (!okTitle)
            {
                okTitle = true;
                *stream << "**" << endl;
                *stream << "** BOUNDARY CONDITIONS" << endl;
                *stream << "**" << endl;
            }
            //通过工厂创建
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorBoundary>("INP", boundary);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setCaseData(_caseData);
            adaptor->setDataObject(boundary);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
            {
                _writer->consoleMessage(3, QString("Write Initial Boundary Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
                return false;
            }
        }
        return true;
    }

    bool FITKAbaqusAdaptorCase::writeInitialConditions()
    {
        if (!_writer || !_caseData)return false;
        //获取预定义管理器
        Interface::FITKAbaPredefinedFieldManager* predefinedFieldManager = _caseData->getPredefinedFieldManager();
        if (!predefinedFieldManager)return false;
        int count = predefinedFieldManager->getDataCount();
        QTextStream* stream = _writer->getStream();
        //获取initStepId
        auto stepManager = _caseData->getStepManager();
        if (!stepManager)return false;
        if (stepManager->getDataCount() < 1)return false;
        int initStepId = stepManager->getDataByIndex(0)->getDataObjectID();
        bool okTitle = false;
        for (int i = 0; i < count; ++i)
        {
            auto predefinedFieldData = dynamic_cast<Interface::FITKAbaAbstractPredefinedField*>(predefinedFieldManager->getDataByIndex(i));
            if (!predefinedFieldData)continue;
            if (predefinedFieldData->getCreatedStep() != initStepId)continue;
            if (!okTitle)
            {
                okTitle = true;
                *stream << "**" << endl;
                *stream << "** PREDEFINED FIELDS" << endl;
                *stream << "**" << endl;
            }
            //通过工厂创建
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorPredefinedField>("INP", predefinedFieldData);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setCaseData(_caseData);
            adaptor->setWriterData("", initStepId);
            adaptor->setDataObject(predefinedFieldData);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
            {
                _writer->consoleMessage(3, QString("Write PredefinedField Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
                return false;
            }
        }
        return true;
    }

    bool FITKAbaqusAdaptorCase::writeInteractionProperty()
    {
        if (!_writer || !_caseData)return false;
        //获取相互作用属性管理器
        auto interactionPropertyManager = _caseData->getInteractionPropertyManager();
        int count = interactionPropertyManager->getDataCount();
        QTextStream* stream = _writer->getStream();
        //写出相互作用属性
        bool okTitle = false;
        for (int i = 0; i < count; ++i)
        {
            auto interactionProp = dynamic_cast<Interface::FITKAbaAbstractInteractionProperty*>(interactionPropertyManager->getDataByIndex(i));
            if (!interactionProp)continue;
            if (!okTitle)
            {
                okTitle = true;
                *stream << "**" << endl;
                *stream << "** INTERACTION PROPERTIES" << endl;
                *stream << "**" << endl;
            }
            //通过工厂创建
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorInteractionProperty>("INP", interactionProp);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setCaseData(_caseData);
            adaptor->setDataObject(interactionProp);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
            {
                _writer->consoleMessage(3, QString("Write Interaction Property Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
                return false;
            }
        }
        return true;
    }

    bool FITKAbaqusAdaptorCase::writeInteraction()
    {
        if (!_writer || !_caseData)return false;

        QTextStream* stream = _writer->getStream();
        //获取initStepId
        auto stepManager = _caseData->getStepManager();
        if (!stepManager)return false;
        if (stepManager->getDataCount() < 1)return false;
        int initStepId = stepManager->getDataByIndex(0)->getDataObjectID();
        //写出(Interaction)相互作用
        Interface::FITKAbaInteractionManager* _interactionManager = _caseData->getInteractionManager();
        if (_interactionManager == nullptr) return false;
        Interface::FITKAbaAbstractInteraction* initInteraction{};
        for (int i = 0; i < _interactionManager->getDataCount(); ++i)
        {
            auto interction = _interactionManager->getDataByIndex(i);
            if (interction == nullptr || interction->getInteractionType() != Interface::FITKAbaAbstractInteraction::FITKAbaInteractionType::GeneralContactExplicit) continue;

            if (interction->getCreatedStep() == initStepId)
            {
                initInteraction = interction;
                break;
            }
        }
        if (initInteraction == nullptr) return true;

        *stream << "**" << endl;
        *stream << "** INTERACTIONS" << endl;
        *stream << "**" << endl;

        //用于判断边界是否激活
        if (!initInteraction->getActiveState()) return true;
        //QString op;
        //int stepId = this->writeBoundaryDataType(interaction, op);
        //if (stepId == 0)continue;

        *stream << QString("** Interaction: general_contact") << endl;
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorInteraction>("INP", initInteraction);
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setCaseData(_caseData);
        auto initStepData = _caseData->getStepManager()->getDataByName("Initial");
        adaptor->setStepData(initStepData);
        adaptor->setDataObject(initInteraction);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Interaction Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusAdaptorCase::writeConnectorBehavior()
    {
        if (!_caseData || !_writer)return false;
        //获取装配
        Interface::FITKAbaAssembly* assemblyData = _caseData->getAssembly();
        if (!assemblyData)return false;
        //获取装配下的连接器指派的管理
        Interface::FITKAbaConnectorAssignmentManager* assignmentConnectManager = assemblyData->getConnectorAssignManager();
        if (!assignmentConnectManager)return false;
        //写出连接器指派
        int count = assignmentConnectManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaConnectorAssignment* assignConnect = assignmentConnectManager->getDataByIndex(i);
            if (!assignConnect)continue;
            Interface::FITKAbaConnectorSection* sectionConnect = assignConnect->getTSectionObj<Interface::FITKAbaConnectorSection>();
            if (!sectionConnect || sectionConnect->getAllBehaviors().isEmpty())continue;
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorConnectorSection>("INP", sectionConnect);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setDataObject(sectionConnect);
            adaptor->setWriteBehavior(true);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
                _writer->consoleMessage(3, QString("write ConnectAssignment Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            if (!ok) return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorCase::writeStep(Interface::FITKAbaAbstractStep* step)
    {
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorStep>("INP", "Interface::FITKAbaAbstractStep");
        if (adaptor == nullptr)
            return false;
        //设置读取器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(step);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Step Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusAdaptorCase::writeTimePoints()
    {
        if (!_writer || !_caseData)return false;
        //获取相互作用属性管理器
        auto timePointManager = _caseData->getTimePointsManager();
        if (!timePointManager)return false;
        int count = timePointManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaTimePoints* timePointData = timePointManager->getDataByIndex(i);
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorTimePoints>("INP", timePointData);
            if (adaptor == nullptr)
            {
                _reader->consoleMessage(3, "Create AbaTimePoints Error.");
                return false;
            }
            //设置读取器
            adaptor->setFileWriter(_writer);
            adaptor->setDataObject(timePointData);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
            {
                _writer->consoleMessage(3, QString("Write TimePoint Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
                return false;
            }
        }
        return true;
    }


    //写出时 计算进度 预计分配 
    //part占用70% 
    //assembly占用15%
    //material占用5%
    //step load optput等 占用10%
    void FITKAbaqusAdaptorCase::sendCalculateProgress(int step, int count, int index)
    {
        if (_writer == nullptr) return;
        if (count == 0) count = index = 1;
        index = count < index ? count : index;

        int progress = 0;
        //计算百分比
        if (step == 1)
        {
            progress = 70 / count * index;
        }
        else if (step == 2)
        {
            progress = 15 / count * index + 70;
        }
        else if (step == 3)
        {
            progress = 5 / count * index + 70 + 15;
        }
        else if (step == 4)
        {
            progress = 10 / count * index + 70 + 15 + 5;
        }
        _writer->sendCalculateProgress(progress);
    }
}



